#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPointF>
#include <QSize>
#include <QStringLiteral>
#include <QFontMetricsF>
#include <QTime>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect(&gameTimer, SIGNAL(timeout()), this, SLOT(gameLoop()));
    this->resize( QSize( GAME_MAP_WIDTH+100+2/*2像素是线*/, GAME_MAP_HEIGHT ));
    initial();

}

MainWindow::~MainWindow()
{
    delete ui;
}
/**
 * @brief initial
 */
void MainWindow:: initial(){
    message="开始游戏";
    food = new QPoint();
    qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
    int x=qrand() %RECT_WIDTH;
    int y=qrand() %RECT_HEIGHT;
    randFood(x,y);
    snakePointList=new QList<QPoint>();
    snakePointList->append(QPoint(100,300));
    snakePointList->append(QPoint(120,300));
    snakePointList->append(QPoint(140,300));
    gameTimer.setInterval(10000/this->stage);
    this->start();
    this->startGame=true;


}
void MainWindow::restart(){
    message="游戏开始";
    this->stop();
    this->score=0;
    this->stage=10;
    snakePointList->clear();
    snakePointList->append(QPoint(100,300));
    snakePointList->append(QPoint(120,300));
    snakePointList->append(QPoint(140,300));
    gameTimer.setInterval(10000/this->stage);
    qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
    int x=qrand() %RECT_WIDTH;
    int y=qrand() %RECT_HEIGHT;
    randFood(x,y);
    this->start();
    this->startGame=true;
    this->repaint();
}
/**
  随机出现食物
 * @brief MainWindow::randFood
 */
void MainWindow::randFood(int x,int y){
    qDebug()<<"随机产生食物:"<<"X:"<<x*RECT_WIDTH<<" Y:"<<y*RECT_WIDTH;
    food->setX(x*RECT_WIDTH);
    food->setY(y*RECT_WIDTH);
    this->repaint();
}
/**
  核心绘图
 * @brief MainWindow::paintEvent
 */
void MainWindow::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.setPen(QColor(0, 160, 230));
    QFont font;
    font.setFamily("Microsoft YaHei");
    painter.setFont(font);
    //画竖线
    for(int w=0;w<=GAME_MAP_WIDTH;w+=RECT_WIDTH){
        painter.drawLine(QPointF(w, 0), QPointF(w, GAME_MAP_HEIGHT));
    }
    //画横线
    for(int h=0;h<=GAME_MAP_HEIGHT;h+=RECT_HEIGHT){
        painter.drawLine(QPointF(0, h), QPointF(GAME_MAP_WIDTH, h));
    }
    //画蛇
    QPoint headPoint=snakePointList->at(0);
    painter.setBrush(Qt::red);
    painter.drawEllipse(headPoint.x(), headPoint.y(),20,20);
    for ( int i=1; i!=snakePointList->size(); ++i )
    {
        QColor qcolor=QColor::fromHsl(rand()%360,rand()%256,rand()%200);
        QPoint point =snakePointList->at(i);
        painter.fillRect(QRect(point.x(),point.y() ,RECT_WIDTH,RECT_HEIGHT), QBrush(QColor(qcolor.red(),qcolor.green(),qcolor.blue())));
    }
    //食物
    painter.setBrush(Qt::green);
    painter.drawEllipse(food->x(), food->y(),20,20);
    //显示关卡
    painter.setBrush(Qt::NoBrush);
    painter.setPen(Qt::black);
    painter.drawRect(GAME_MAP_WIDTH,0,100,25);
    painter.drawText(GAME_MAP_WIDTH+RECT_HEIGHT,RECT_HEIGHT,QString("当前第 ")+QString::number(this->stage-9)+QString(" 关") );

    //显示积分
    painter.setPen(Qt::black);
    painter.drawRect(GAME_MAP_WIDTH,0,100,50);
    painter.drawText(GAME_MAP_WIDTH+RECT_HEIGHT,RECT_HEIGHT*2+2,QString("当前积分:")+QString::number(this->score));

    //显示信息
    painter.setPen(Qt::black);
    painter.drawRect(GAME_MAP_WIDTH,0,100,75);
    painter.drawText(GAME_MAP_WIDTH+RECT_HEIGHT,RECT_HEIGHT*3+4,message);

    //游戏帮助
    painter.setPen(Qt::black);
    painter.drawRect(GAME_MAP_WIDTH+2,200,100-2,60);
    painter.drawText(GAME_MAP_WIDTH+2,220,QString("WASD控制方向"));
    painter.drawText(GAME_MAP_WIDTH+2,240,QString("空格重新开始"));


}
/**
 * 鼠标按下
 * @brief MainWindow::mousePressEvent
 */
void MainWindow::mousePressEvent(QMouseEvent *)
{
    //qDebug()<<"鼠标按下";
}
/**
  鼠标释放
 * @brief MainWindow::mouseReleaseEvent
 */
void MainWindow::mouseReleaseEvent(QMouseEvent *event)
{

}
/**
  鼠标移动
 * @brief MainWindow::mouseMoveEvent
 * @param e
 */
void MainWindow::mouseMoveEvent(QMouseEvent *e)
{
    //qDebug()<<"鼠标释放"<<e->pos().x();
}
/**
  键盘按下
 * @brief MainWindow::keyPressEvent
 * @param evt
 */

void MainWindow::keyPressEvent(QKeyEvent *event)
{
    if(!startGame &&event->key()!=Qt::Key_Space){
        return;
    }
    switch (event->key()) {
    case  Qt::Key_W:
        if (headDirection==DIRECTION_DOWN){
            qDebug()<<"不允许180度转弯:"<<endl;
            return;
        }else {
            headDirection=DIRECTION_UP;
            move();
        }


        break;
    case  Qt::Key_A:
        if (headDirection==DIRECTION_RIGHT){
            qDebug()<<"不允许180度转弯:"<<endl;
            return;
        }else {
            headDirection=DIRECTION_LEFT;
            move();

        }
        break;
    case  Qt::Key_S:
        if (headDirection==DIRECTION_UP){
            qDebug()<<"不允许180度转弯:"<<endl;
            return;
        }else {
            headDirection=DIRECTION_DOWN;
            move();
        }
        break;
    case  Qt::Key_D:
        if (headDirection==DIRECTION_LEFT){
            qDebug()<<"不允许180度转弯:"<<endl;
            return;
        }else {
            headDirection=DIRECTION_RIGHT;
            move();
        }
        break;
        //重新开始
    case Qt::Key_Space:
        restart();
    default:
        break;
    }


}
/**
  事件处理
 * @brief MainWindow::event
 * @param event
 * @return
 */
bool MainWindow::event(QEvent *event)
{
    return QMainWindow::event(event);
}
/**
  移动函数
 * @brief MainWindow::move
 */
void MainWindow::move(){

    //死亡判断
    //qDebug()<<"当前方向:"<<headDirection<<" Food:" <<*food <<"头结点:"<<headPoint<<endl;
    switch (headDirection) {
    case DIRECTION_LEFT:
        headPoint=snakePointList->at(0);
        if(headPoint.x()<RECT_WIDTH){
            qDebug()<<"你撞左面墙了!"<<endl;
            stop();
            return;
        }
        snakePointList->removeAt(snakePointList->size()-1);
        snakePointList->insert(0, QPoint(headPoint.x()-RECT_WIDTH,headPoint.y()));
        this->repaint();
        //吃食物
        headPoint=snakePointList->at(0);
        if(food->x()==headPoint.x()&&food->y()==headPoint.y()){
            this->score+=1;
            qDebug()<<"吃到了 score:"<<this->score;
            snakePointList->insert(0, QPoint(food->x()-RECT_WIDTH,food->y()));
            this->repaint();
            qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
            int x=qrand() %RECT_WIDTH;
            int y=qrand() %RECT_HEIGHT;
            randFood(x,y);
            if(this->score %10 ==0 &&this->score!=0){
                this->stage=this->stage+1;
                gameTimer.stop();
                gameTimer.setInterval(10000/this->stage);
                gameTimer.start();
            }
            this->repaint();


        }
        qDebug()<<"当前方向:"<<headDirection<<" Food:" <<*food <<"头结点:"<<headPoint<<endl;

        break;
    case DIRECTION_UP:
        headPoint=snakePointList->at(0);

        if(headPoint.y()<RECT_HEIGHT){
            qDebug()<<"你撞上面墙了!"<<endl;
            stop();
            return;
        }
        snakePointList->removeAt(snakePointList->size()-1);
        snakePointList->insert(0, QPoint(headPoint.x(),headPoint.y()-RECT_HEIGHT));
        this->repaint();
        //吃食物
        headPoint=snakePointList->at(0);
        if(food->x()==headPoint.x()&&food->y()==headPoint.y()){
            this->score+=1;
            qDebug()<<"吃到了 score:"<<this->score;
            snakePointList->insert(0, QPoint(food->x(),food->y()-RECT_HEIGHT));
            this->repaint();
            qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
            int x=qrand() %RECT_WIDTH;
            int y=qrand() %RECT_HEIGHT;
            randFood(x,y);
            if(this->score %10 ==0 &&this->score!=0){
                this->stage=this->stage+1;
                gameTimer.stop();
                gameTimer.setInterval(10000/this->stage);
                gameTimer.start();
            }
            this->repaint();


        }
        break;
    case DIRECTION_RIGHT:
        headPoint=snakePointList->at(0);

        if(headPoint.x()>=GAME_MAP_WIDTH-RECT_WIDTH){
            qDebug()<<"你撞右面墙了!"<<endl;
             stop();

            return;
        }

        snakePointList->removeAt(snakePointList->size()-1);
        snakePointList->insert(0, QPoint(headPoint.x()+RECT_WIDTH,headPoint.y()));
        this->repaint();

        //吃食物
        headPoint=snakePointList->at(0);
        if(food->x()==headPoint.x()&&food->y()==headPoint.y()){
            this->score+=1;
            qDebug()<<"吃到了 score:"<<this->score;
            snakePointList->insert(0, QPoint(food->x()+RECT_WIDTH,food->y()));
            this->repaint();
            qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
            int x=qrand() %RECT_WIDTH;
            int y=qrand() %RECT_HEIGHT;
            randFood(x,y);
            if(this->score %10 ==0 &&this->score!=0){
                this->stage=this->stage+1;
                gameTimer.stop();
                gameTimer.setInterval(10000/this->stage);
                gameTimer.start();
            }
            this->repaint();


        }
        break;
    case DIRECTION_DOWN:
        headPoint=snakePointList->at(0);
        if(headPoint.y()>=GAME_MAP_HEIGHT-RECT_HEIGHT){
            qDebug()<<"你撞下面墙了!"<<endl;
             stop();

            return;
        }

        snakePointList->removeAt(snakePointList->size()-1);
        snakePointList->insert(0, QPoint(headPoint.x(),headPoint.y()+RECT_HEIGHT));
        this->repaint();

        //吃食物
        headPoint=snakePointList->at(0);
        if(food->x()==headPoint.x()&&food->y()==headPoint.y()){
            this->score+=1;
            qDebug()<<"吃到了 score:"<<this->score;
            snakePointList->insert(0, QPoint(food->x(),food->y()+RECT_HEIGHT));
            this->repaint();
            qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
            int x=qrand() %RECT_WIDTH;
            int y=qrand() %RECT_HEIGHT;
            randFood(x,y);
            if(this->score %10 ==0 &&this->score!=0){
                this->stage=this->stage+1;
                gameTimer.stop();
                gameTimer.setInterval(10000/this->stage);
                gameTimer.start();
            }
            this->repaint();

        }
        break;
    default:
        break;
    }
}

void MainWindow::gameLoop(){
    move();
}


void  MainWindow::stop(){
    message="游戏停止!";
    gameTimer.stop();
    this->startGame=false;

    this->repaint();

}
void  MainWindow::start(){
    gameTimer.start();
}
void MainWindow::help(){

}
